import Mat3 from "./mat3";
import Color from "./color";
import Linear from "./linear";

class Animate {
  target = null;
  duration = 0;
  easing = null;
  onUpdate = null;
  onComplete = null;
  to = null;
  from = null;
  startTS = 0;
  constructor(e, t, n, r, i, s) {
    let o = this;
    (o.target = e),
      (o.to = n),
      (o.duration = t),
      (o.easing = typeof r == "function" ? r : Linear.easeNone),
      (o.onUpdate = i),
      (o.onComplete = s);
  }
  init(e) {
    let t = this;
    (t.startTS = e), (t.from = {});
    for (let n in t.to)
      if (t.to.hasOwnProperty(n) && typeof t.target[n] == "function") {
        let r = t.target[n],
          i = r.call(t.target);
        t.from[n] = i.clone ? i.clone() : i;
      }
  }
  update(n) {
    let r = this,
      i = Math.min(n - r.startTS, r.duration),
      s = r.easing(i, 0, 1, r.duration);
    for (let o in r.from)
      if (r.from.hasOwnProperty(o)) {
        let u = r.from[o],
          a = r.to[o];
        if (o == "matrix") {
          let f = new Mat3();
          (f.a = u.a + (a.a - u.a) * s),
            (f.b = u.b + (a.b - u.b) * s),
            (f.c = u.c + (a.c - u.c) * s),
            (f.d = u.d + (a.d - u.d) * s),
            (f.tx = u.tx + (a.tx - u.tx) * s),
            (f.ty = u.ty + (a.ty - u.ty) * s),
            r.target.matrix(f);
        } else if (o == "bgColor") {
          let l = u.r() + (a.r() - u.r()) * s,
            c = u.g() + (a.g() - u.g()) * s,
            h = u.b() + (a.b() - u.b()) * s,
            p = u.a() + (a.a() - u.a()) * s;
          r.target.bgColor(Color.colorWithRGBA(l, c, h, p));
        } else if (isNaN(u) === !1 && isNaN(a) === !1) {
          let d = u + (a - u) * s;
          r.target[o](d);
        }
      }
    typeof r.onUpdate == "function" && r.onUpdate(r.target, s);
    let v = n - r.startTS >= r.duration;
    return v && typeof r.onComplete == "function" && r.onComplete(r.target), v;
  }
  jumpToEnd = function () {
    let e = this;
    e.update(e.startTS + e.duration);
  };
}

export default Animate;
